Romberg's method

In numerical analysis, Romberg's method (Romberg 1955) is used to estimate the definite integral

 \int_a^b f(x) \, dx

by applying Richardson extrapolation (Richardson 1910) repeatedly on the trapezium rule or the rectangle rule (midpoint rule). The estimates generate a triangular array. Romberg's method is a Newton–Cotes formula – it evaluates the integrand at equally-spaced points. The integrand must have continuous derivatives, though fairly good results may be obtained if only a few derivatives exist. If it is possible to evaluate the integrand at unequally-spaced points, then other methods such as Gaussian quadrature and Clenshaw–Curtis quadrature are generally more accurate.

The method is named after Werner Romberg (1909–2003), who published the method in 1955.

Contents

Method

The method can be defined inductively

R(0,0) = \frac{1}{2} (b-a) (f(a) %2B f(b))
R(n,0) = \frac{1}{2} R(n-1,0) %2B h_n \sum_{k=1}^{2^{n-1}} f(a %2B (2k-1)h_n)
R(n,m) = R(n,m-1) %2B \frac{1}{4^m-1} (R(n,m-1) - R(n-1,m-1))

or

R(n,m) = \frac{1}{4^m-1} ( 4^m R(n,m-1) - R(n-1,m-1))

where

 n \ge 1 \,
 m \ge 1 \,
 h_n = \frac{b-a}{2^n}.

In big O notation, the error for R(nm) is (Mysovskikh 2002):

 O\left(h_n^{2m%2B2}\right). \,

The zeroeth extrapolation, R(n, 0), is equivalent to the trapezoidal rule with 2n + 1 points; the first extrapolation, R(n, 1), is equivalent to Simpson's rule with 2n + 1 points. The second extrapolation, R(n, 2), is equivalent to Boole's rule with 2n + 1 points. Further extrapolations differ from Newton Cote's Formulas. In particular further Romberg extrapolations expand on Boole's rule in very slight ways, modifying weights into ratios similar as in Boole's rule. In contrast, further Newton Cotes methods produce increasingly differing weights, eventually leading to large positive and negative weights. This is indicative of how large degree interpolating polynomial Newton Cotes methods fail to converge for many integrals, while Romberg integration is more stable.

When function evaluations are expensive, it may be preferable to replace the polynomial interpolation of Richardson with the rational interpolation proposed by Bulirsch & Stoer (1967).

A geometric example

To estimate the area under a curve the trapezoid rule is applied first to one-piece, then two, then four, and so on.

After trapezoid rule estimates are obtained Richardson's Extrapolation is applied

Number of pieces Trapezoid estimates First iteration second iteration third iteration
(4MA-LA)/3* (16MA-LA)/15 (64MA-LA)/63
1 0 (4*480-0)/3 = 640 (16*880-640)/15 =896 (64*1015.11-896)/63 = 1017.002
2 480 (4*780-480)/3 = 880 (16*1006.67-880)/15 = 1015.11..
4 780 (4*950-780)/3 =1006.666..
8 950

Example

As an example, the Gaussian function is integrated from 0 to 1, i.e. the error function erf(1) ≈ 0.842700792949715. The triangular array is calculated row by row and calculation is terminated if the two last entries in the last row differ less than 10−8.

 0.77174333
 0.82526296  0.84310283
 0.83836778  0.84273605  0.84271160
 0.84161922  0.84270304  0.84270083  0.84270066
 0.84243051  0.84270093  0.84270079  0.84270079  0.84270079

The result in the lower right corner of the triangular array is accurate to the digits shown. It is remarkable that this result is derived from the less accurate approximations obtained by the trapezium rule in the first column of the triangular array.

Implementation

Here is an example of a computer implementation of the Romberg method (In the C programming language), it needs one vector and one variable; it also needs a sub-routine trapeze:

 #include <stdio.h>
 #include <stdlib.h>
 #include <math.h>
 #define MAX 6
 
int main()
{
    double s[MAX];
    int i,k;
    double var ;
    for (i = 1; i< MAX; i++)
        s[i] = 1;
 
    for (k=1; k< MAX; k++)
    {
        for (i=1; i <=k; i++)
        {
            if (i==1)
            {
                var = s[i];
                s[i] = Trap(0, 1, pow(2, k-1));     // sub-routine trapeze 
            }                                       // integrated from 0 and 1
                                                    /* pow() is the number of subdivisions*/
            else
            {
                s[k]= ( pow(4 , i-1)*s[i-1]-var )/(pow(4, i-1) - 1); 
 
                var = s[i];
                s[i]= s[k];  
            }
         }
 
        for (i=1; i <=k; i++)
            printf ("  %f  ", s[i]);
 
        printf ("\n");
    }
 
    return 0;
}

References

External links